import { dao3CfgProvider } from "@ap/util/mapFile/dao3CfgQuick";

import { PackageConfig } from "@ap/types/config";
import { BASE_CFG_JSON, getPackageJson } from "@ap/util/packageJson";
import { arenaErrorMsg } from "@ap/util/vscode/errorMsg";
import { showErrorMessage } from "@ap/util/vscode/message";
import getFilePath from "@ap/util/vscode/getFilePath";
import { tempPath } from "@ap/util/tempPath";
import path from "path";
import { safeReadJSONC } from "../data";

function solveIfNotAbsolute(temp: string, base?: string) {
  if (tempPath) {
    return path.isAbsolute(temp) ? temp : path.resolve(base ?? tempPath, temp);
  }
  return temp;
}

export async function getPathAndFileName2Config(dao3CfgByDir?: boolean) {
  // 分别获取文件和地图的配置信息。
  const arenaProFileConfig =
    await getPackageJson<PackageConfig["file"]>("file");
  const arenaProOutputNameConfig =
    await getPackageJson<PackageConfig["outputAndUpdate"]>("outputAndUpdate");
  // 校验配置信息是否完整，如果不完整则显示错误消息并终止操作。
  if (!arenaProFileConfig) {
    showErrorMessage(arenaErrorMsg.PROFILE_AND_MAP_INFORMATION);
    return;
  }
  if (!arenaProFileConfig.typescript) {
    showErrorMessage(arenaErrorMsg.CONFIGURE_TYPESCRIPT_INFORMATION);
    return;
  }

  const pkgPath = dao3CfgByDir
    ? path.parse(getFilePath(BASE_CFG_JSON) || "").dir
    : getFilePath() || "";
  if (!pkgPath) {
    showErrorMessage(arenaErrorMsg.CONFIGURE_PACKAGE_JSON);
    return;
  }
  let serverEntry: string | undefined;
  let clientEntry: string | undefined;
  let arenaProClientOutputName = undefined;
  let arenaProServerOutputName = undefined;
  if (
    arenaProOutputNameConfig &&
    typeof arenaProOutputNameConfig[0] === "object"
  ) {
    arenaProClientOutputName = "_client_" + arenaProOutputNameConfig[0].name;
    arenaProServerOutputName = "_server_" + arenaProOutputNameConfig[0].name;
    serverEntry = arenaProOutputNameConfig[0].serverEntry;
    clientEntry = arenaProOutputNameConfig[0].clientEntry;
  } else if (arenaProOutputNameConfig && arenaProOutputNameConfig.length > 0) {
    arenaProClientOutputName = "_client_" + arenaProOutputNameConfig[0];
    arenaProServerOutputName = "_server_" + arenaProOutputNameConfig[0];
    serverEntry = arenaProFileConfig.typescript.server.entry;
    clientEntry = arenaProFileConfig.typescript.client.entry;
  }
  const serverBase = solveIfNotAbsolute(
    arenaProFileConfig.typescript.server.base || "./server",
    pkgPath ?? "",
  );
  const clientBase = solveIfNotAbsolute(
    arenaProFileConfig.typescript.client.base || "./client",
    pkgPath ?? "",
  );

  return {
    server: {
      base: serverBase,
      path: serverEntry || "src/App.ts",
      fileName: arenaProServerOutputName,
    },
    client: {
      base: clientBase,
      path: clientEntry || "src/clientApp.ts",
      fileName: arenaProClientOutputName,
    },
  };
}

function calculateDist(
  tsconfigPath: string,
  tsconfig: any,
  base: string,
): string {
  const rootDir = path.resolve(
    path.parse(tsconfigPath).dir,
    tsconfig?.compilerOptions?.rootDir || path.parse(tsconfigPath).dir,
  );
  return path.resolve(
    path.resolve(
      path.parse(tsconfigPath).dir,
      tsconfig?.compilerOptions?.outDir || ".",
    ),
    path.relative(rootDir, base),
  );
}

export async function getDist(base: string) {
  const tsconfigPath = path.resolve(base, "tsconfig.json");
  const tsconfig = await safeReadJSONC(tsconfigPath);
  return calculateDist(tsconfigPath, tsconfig, base);
}
